﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Net;

namespace OsuKeyboard
{
    class UpdateCheck
    {
        #region 字段
        public const string ServerIP = @"http://git.oschina.net/Antecer/";//服务器地址
        public const string Project = @"OsuKeyboard";//工程名称
        public const string versionLink = ServerIP + Project + @"/commits/master";//程序版本更新历史
        public const string UpdateVer = ServerIP + Project + @"/raw/master/" + Project + @"/Properties/AssemblyInfo.cs";//程序最新版本号（判定是否需要更新）
        public const string UpdateExe = ServerIP + Project + @"/raw/master/" + Project + @"/bin/Release/" + Project + @".exe";//程序更新地址
        public const string Commits = ServerIP + Project + @"/commits/master";//更新历史
        public static bool Now = false;//设立更新状态标志
        #endregion

        #region 更新流程
        public static void Start()
        {
            Thread UpdatStart = new Thread(new ThreadStart(Updating));//创建一个新线程来执行更新
            UpdatStart.IsBackground = true;   //设置此线程为后台线程
            UpdatStart.Start();               //启动线程
        }

        /// <summary>
        /// 程序更新线程
        /// </summary>
        public static void Updating()
        {
            String FilePath = Application.ExecutablePath.Replace(".EXE", ".exe");//本地文件路径
            if (File.Exists(FilePath + ".old")) File.Delete(FilePath + ".old");//删除旧文件

            Version newVersion = new Version(versioncheck(UpdateVer));      //获取更新程序版本号
            Version oldVersion = new Version(Application.ProductVersion);   //获取当前程序版本号
            if (newVersion > oldVersion)
            {
                DialogResult dr = MessageBox.Show("当前版本：" + oldVersion + "\r\n最新版本：" + newVersion.ToString() + "\r\n是否更新到最新版本？\r\n详情：" + Commits, "Update 软件更新", MessageBoxButtons.YesNo);
                if (dr == DialogResult.Yes)
                {
                    Now = true;
                    if (DownloadFile(UpdateExe, FilePath + ".tmp"))
                    {
                        Thread.Sleep(1000);
                    }
                    else
                    {
                        MessageBox.Show("更新失败！");
                        Thread.Sleep(1000);
                        Now = false;
                        return;
                    }
                }
            }
            if (File.Exists(FilePath + ".tmp"))
            {
                File.Move(FilePath, FilePath + ".old");
                File.Move(FilePath + ".tmp", FilePath);
                while (!File.Exists(FilePath)) Thread.Sleep(1000);  // 等待更新文件准备完成
                MessageBox.Show("更新完成！");
                Application.Restart();
                Application.ExitThread();
            }
            Now = false;
        }
        /// <summary>
        /// 从指定网页提取字符串
        /// </summary>
        /// <returns>返回指定字符串</returns>
        public static string versioncheck(string url)
        {
            string vertext = "0.0.0.0";
            try
            {
                WebRequest request = WebRequest.Create(url);
                WebResponse response = request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), true);
                vertext = reader.ReadToEnd();
                reader.Dispose();
                response.Close();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
            if (vertext.Contains("AssemblyFileVersion"))
            {
                vertext = vertext.Substring(vertext.LastIndexOf("AssemblyFileVersion"));
                vertext = vertext.Replace("AssemblyFileVersion(\"", "").Replace("\")]", "");
            }
            return vertext;
        }
        /// <summary>
        /// http文件下载
        /// </summary>
        /// <param name="downLoadUrl">文件的url路径</param>
        /// <param name="saveFullName">需要保存在本地的路径(包含文件名)</param>
        /// <returns>成功返回true，失败返回false</returns>
        public static bool DownloadFile(string downLoadUrl, string savePathName)
        {
            downLoadUrl = downLoadUrl.Replace(@"\", "/");
            savePathName = savePathName.Replace("/", @"\");
            string cachePath = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);//获取IE临时目录(作为下载缓存使用)
            cachePath = cachePath + savePathName.Remove(0, savePathName.LastIndexOf(@"\"));       //设置下载临时文件
            String GreatFile = savePathName.Substring(0, savePathName.LastIndexOf(@"\"));         //创建目标存放路径
            if (!Directory.Exists(GreatFile)) Directory.CreateDirectory(GreatFile);
            HttpWebRequest request = null;
            try
            {
                request = (HttpWebRequest)HttpWebRequest.Create(downLoadUrl);//根据URL获取远程文件流
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream sr = response.GetResponseStream();
                Stream sw = new FileStream(cachePath, FileMode.Create);//创建本地文件写入流

                Decimal WebFileBytes = response.ContentLength;
                Decimal DownloadByte = 0;
                Byte[] buf = new Byte[1024];//创建数据接收缓冲区
                Int32 osize = sr.Read(buf, 0, (int)buf.Length);
                while (osize > 0)
                {
                    DownloadByte += osize;
                    sw.Write(buf, 0, osize);
                    osize = sr.Read(buf, 0, (int)buf.Length);
                }
                sw.Close();
                sr.Close();
                File.Delete(savePathName);          //删除旧文件
                File.Move(cachePath, savePathName); //添加新文件
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                if (request != null) request.Abort();
                return false;
            }
        }
        #endregion
    }
}
